﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Configuration.Provider;
using System.Collections.Specialized;
using System.Threading;
using Medianamik.Core.DAL;
using Medianamik.Core.Security;

namespace Medianamik.Core
{
    internal class NodeTypeProvider : ProviderBase
    {
        #region Fields

        private ReaderWriterLockSlim _lock = new ReaderWriterLockSlim();
        private INodeTypeDALProvider _nodeTypeDalProvider;

        #endregion

        #region .ctors

        public NodeTypeProvider()
            : this(DALProviderManager.DALProvider.NodeTypeDALProvider)
        {
            
        }

        internal NodeTypeProvider(INodeTypeDALProvider nodeTypeDalProvider)
        {
            _nodeTypeDalProvider = nodeTypeDalProvider;
            Initialize("NodeTypeProvider", new NameValueCollection());
            
        }

        #endregion
        
        private List<NodeType> _allTypes;
        public List<NodeType> AllTypes
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allTypes;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private List<NodeTypeInterface> _allInterfaces;
        public List<NodeTypeInterface> AllInterfaces
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allInterfaces;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private List<NodeTypeProperty> _allProperties;
        public List<NodeTypeProperty> AllProperties
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allProperties;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private List<NodeTypeInterfaceProperty> _allInterfaceProperties;
        public List<NodeTypeInterfaceProperty> AllInterfaceProperties
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allInterfaceProperties;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private List<HierarchicalRule> _allHierarchicalRules;
        public IEnumerable<HierarchicalRule> AllHierarchicalRules
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allHierarchicalRules;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }
       

        private List<NodeType> _unrestrictedTypes;
        public IEnumerable<NodeType> UnrestrictedTypes
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _unrestrictedTypes;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        private List<TypeTemplate> _allTemplates;
        public IEnumerable<TypeTemplate> AllTemplates
        {
            get
            {
                _lock.EnterReadLock();
                try
                {
                    return _allTemplates;
                }
                finally
                {
                    _lock.ExitReadLock();
                }
            }
        }

        #region Methods

        public override void Initialize(string name, NameValueCollection config)
        {
            base.Initialize(name, config);

            LoadNodeTypes();
        }

        public void Reload()
        {
            _lock.EnterWriteLock();
            try
            {
                LoadNodeTypes();
            }
            finally
            {
                _lock.ExitWriteLock();
            }
        }

        private void LoadNodeTypes()
        {
            _allTypes = _nodeTypeDalProvider.GetAllTypes(true);
            _allInterfaces = _nodeTypeDalProvider.GetAllInterfaces().ToList();
            _allProperties = _nodeTypeDalProvider.GetAllNodeTypeProperties().ToList();
            _allInterfaceProperties = _nodeTypeDalProvider.GetAllNodeTypeInterfaceProperties().ToList();
            _allHierarchicalRules = _nodeTypeDalProvider.GetAllHierarchicalRules().ToList();
            _allTemplates = _nodeTypeDalProvider.GetAllTemplates().ToList();
            _unrestrictedTypes = (from t1 in _allTypes
                                  where !(from t2 in _allHierarchicalRules
                                          select t2.ItemID).Contains(t1.ID)
                                  select t1).Where(t => !t.IsAbstract && !t.IsManyToMany).ToList();
        }

        #endregion


    }
}
